#include "RTSPStreamThread.h"

RTSPStreamThread::RTSPStreamThread(string pgName, string url, string conf)
{
	tas.threadClass = this;
	tas.progName = pgName;
	tas.urlToPlay = url;
	tas.confFile = conf;
}

RTSPStreamThread::~RTSPStreamThread()
{
	//Nothing
}

int RTSPStreamThread::configureThread()
{
	//Create and initialize a control variable
	int returnVal = 0;

	//Initialize thread attributes
	if((returnVal = pthread_attr_init(&threadAttr))!=0)
	{
		cout << "ERROR : Cannot initialize thread attributes for the thread creation with error "<< returnVal << " - " << strerror(returnVal) << endl;
		return returnVal;
	}

	//Get the scheduler parameters
	if((returnVal = pthread_attr_getschedparam(&threadAttr, &threadSchedParam))!=0)
	{
		cout << "ERROR : Cannot get the scheduler parameter for thread creation with error "<< returnVal << " - " << strerror(returnVal) << endl;
		return returnVal;
	}

	//Assign FIFO policy to the scheduler
	if((returnVal = pthread_attr_setschedpolicy(&threadAttr, SCHED_FIFO))!=0)
	{
		cout << "ERROR : Cannot set the scheduler policy to SCHED_FIFO for the thread creation with error "<< returnVal << " - " << strerror(returnVal) << endl;
		return returnVal;
	}

	//Set the thread priority as high as possible (i.e. 90)
	threadSchedParam.sched_priority = 90;

	//Assign the parameters to the thread
	if((returnVal = pthread_attr_setschedparam(&threadAttr, &threadSchedParam))!=0)
	{
		cout << "ERROR : Cannot change the thread priority and/or set the scheduler parameters for the thread creation with error "<< returnVal << " - " << strerror(returnVal) << endl;
		return returnVal;
	}
	//if everything has performed properly, return 0
	return returnVal;
}


int RTSPStreamThread::launchThread()
{
	//Create and initialize a control variable
	int returnVal=0;

	//Launch the thread routine
	if((returnVal = pthread_create(&threadID, &threadAttr, RTSPStreamClientCore, &tas))!=0)
	{
	    cout << "ERROR : Cannot launch the new thread with error" << returnVal << " - " << strerror(returnVal) << endl << "Exiting the program ..." << endl;
	    exit(1);
	}

	//if everything has performed properly, return 0
	return returnVal;
}


int RTSPStreamThread::joinThread()
{
	//Create and initialize a control variable
	int returnVal=0;

	//Join the thread in order to be sure that it will be completed before the program stops running
	if((returnVal = pthread_join(threadID, NULL))!=0)
	{
		cout << "ERROR : Cannot wait for the thread to finish with error" << returnVal <<" - " << strerror(returnVal) << endl << "Exiting the program ..." << endl;
		exit(1);
	}

	//if everything has performed properly, return 0
	return returnVal;
}


void* RTSPStreamClientCore(void* ptr)
{
	ThreadArgStruct* tas = (ThreadArgStruct*) ptr;

	tas->threadClass->rtspClient = new RTSPStreamClient(tas->progName, tas->urlToPlay, tas->confFile);

	tas->threadClass->rtspClient->prepareClient();
	tas->threadClass->rtspClient->playFromURL();

	return NULL;
}
